package com.starview.star.operators.pio.runtime;

import java.io.File;

import com.starview.platform.data.EvaluationException;
import com.starview.platform.data.IFunction;
import com.starview.platform.data.IRecord;
import com.starview.platform.data.IScalar;
import com.starview.platform.data.IValue;
import com.starview.platform.data.value.NTuple;
import com.starview.platform.data.value.ResourceURI;
import com.starview.platform.resource.ResourceException;
import com.starview.platform.resource.catalog.CatalogException;
import com.starview.star.LanguageException;
import com.starview.star.StarMain;
import com.starview.star.code.repository.DirectoryRepository;
import com.starview.star.code.repository.RepositoryException;
import com.starview.star.compiler.ErrorReport;
import com.starview.star.compiler.util.ApplicationProperties;
import com.starview.star.operators.string.runtime.ValueDisplay;

public class RemoteFunction
{
  public final static File StarClassFilesDir = new File(ApplicationProperties.getProperty("PROGRAM_CLASSFILES", null));

  public static void __call_serialized_thunk(IValue val) throws EvaluationException, ResourceException,
      CatalogException, LanguageException, RepositoryException
  {
    NTuple.NTpl tuple = (NTuple.NTpl) val;

    @SuppressWarnings("unchecked")
    String loc = ((IScalar<String>) tuple.getCell(0)).getValue();
    String pkg = loc.substring(0, loc.lastIndexOf('/')); // strip off line number, etc.

    @SuppressWarnings("unchecked")
    String f = ((IScalar<String>) tuple.getCell(1)).getValue();
    call_thunk_in_package(pkg, f);
  }

  private static void call_thunk_in_package(String pkgStr, String functionName) throws EvaluationException,
      ResourceException, CatalogException, LanguageException, RepositoryException
  {
    ClassLoader defltLoader = Thread.currentThread().getContextClassLoader();
    ErrorReport errors = new ErrorReport();
    DirectoryRepository repository = new DirectoryRepository(RemoteFunction.StarClassFilesDir, false, true,
        defltLoader, errors);

    ResourceURI uri = ResourceURI.parseURI(pkgStr);

    IValue pkg = StarMain.ldPackage(repository, uri, errors);

    if (pkg instanceof IRecord)
      try {
        IValue mn = ((IRecord) pkg).getMember(functionName);
        if (mn instanceof IFunction) {
          IValue args[] = new IValue[0];
          ((IFunction) mn).enter(args);
        } else if (mn != null)
          errors.reportInfo("bad function:" + ValueDisplay.display(mn) + " in " + uri);
      } catch (IllegalArgumentException e) {
        errors.reportInfo(e.getMessage() + " in " + uri);
      }
    if (!errors.isErrorFree())
      throw new LanguageException(errors);
  }

  public static Object _as_binary(IValue f)
  {
    return f;
  }
}
